home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / jwpsrc.zip / GLOSSARY.C < prev    next >
C/C++ Source or Header  |  1993-03-31  |  23KB  |  730 lines

  1. /* Copyright (C) Stephen Chung, 1991-1993.  All rights reserved. */
  2.  
  3. #include "jwp.h"
  4.  
  5. #include "idm.h"
  6.  
  7.  
  8. typedef struct {
  9.     KANJI far *shortcut;
  10.     KANJI far *phrase;
  11.     BOOL dynamic;
  12.     BOOL hidden;
  13. } GLOSSARY;
  14.  
  15.  
  16. static GLOSSARY Glossary[MAXGLOSSARY];
  17.  
  18. static int NrGlossary = 0;
  19. static BOOL GlossaryChanged = FALSE;
  20. static BOOL sizing = FALSE;
  21.  
  22. static KANJI far *CurrentShortCut;
  23. static KANJI far *CurrentPhrase;
  24.  
  25.  
  26.  
  27. static KANJI far *ConvertGlossary (int id, LONG lParam, KANJI *buf)
  28. {
  29.     return (Glossary[lParam].shortcut);
  30. }
  31.  
  32.  
  33.  
  34. static KANJI far *ConvertGlossary1 (int id, LONG lParam, KANJI *buf)
  35. {
  36.     return (Glossary[lParam].phrase);
  37. }
  38.  
  39.  
  40.  
  41. static int GlossaryComp (void const *v1, void const *v2)
  42. {
  43.     GLOSSARY *p1, *p2;
  44.  
  45.     p1 = (GLOSSARY *) v1;
  46.     p2 = (GLOSSARY *) v2;
  47.  
  48.     return (kanjicmp(p1->shortcut, p2->shortcut));
  49. }
  50.  
  51.  
  52.  
  53. void ReadGlossary (char *filename)
  54. {
  55.     int i, j, len, fd;
  56.     OFSTRUCT of;
  57.  
  58.     /* Clear the old glossary */
  59.  
  60.     for (i = 0; i < NrGlossary; i++) {
  61.         if (Glossary[i].shortcut != NULL) FreeBlock(Glossary[i].shortcut);
  62.         if (Glossary[i].phrase != NULL) FreeBlock(Glossary[i].phrase);
  63.         Glossary[i].shortcut = Glossary[i].phrase = NULL;
  64.     }
  65.  
  66.     fd = OpenFile(filename, &of, OF_READ);
  67.     if (fd < 0) return;
  68.  
  69.     /* Read the glossary file */
  70.  
  71.     lseek(fd, 0L, 0);
  72.     read(fd, &NrGlossary, sizeof(int));
  73.  
  74.     for (i = 0; i < NrGlossary; i++) {
  75.         /* Read the options */
  76.         read(fd, &j, sizeof(int));
  77.         Glossary[i].dynamic = j & 0x0001;
  78.         Glossary[i].hidden = j & 0x0002;
  79.  
  80.         /* Read the short-cut */
  81.         read(fd, &len, sizeof(int));
  82.         len *= sizeof(KANJI);
  83.         Glossary[i].shortcut = BlockAlloc(len);
  84.         if (Glossary[i].shortcut == NULL) break;
  85.         _lread(fd, (char far *) Glossary[i].shortcut, len);
  86.  
  87.         /* Read the phrase */
  88.         read(fd, &len, sizeof(int));
  89.         len *= sizeof(KANJI);
  90.         Glossary[i].phrase = BlockAlloc(len);
  91.         if (Glossary[i].shortcut == NULL) break;
  92.         _lread(fd, (char far *) Glossary[i].phrase, len);
  93.     }
  94.  
  95.     close(fd);
  96.  
  97.     if (NrGlossary > 0) {
  98.         qsort(Glossary, NrGlossary, sizeof(GLOSSARY), GlossaryComp);
  99.     }
  100. }
  101.  
  102.  
  103.  
  104. void WriteGlossary (char *filename)
  105. {
  106.     int i, j, len, fd;
  107.     OFSTRUCT of;
  108.  
  109.  
  110.     if (!GlossaryChanged) return;
  111.  
  112.     fd = OpenFile(filename, &of, OF_WRITE | OF_CREATE);
  113.     if (fd < 0) {
  114.         ErrorMessage(global.hwnd, "Cannot create glossary file %s!", filename);
  115.         return;
  116.     }
  117.  
  118.     for (i = j = 0; i < NrGlossary; i++) {
  119.         if (Glossary[i].shortcut != NULL) j++;
  120.     }
  121.  
  122.     lseek(fd, 0L, 0);
  123.     write(fd, &j, sizeof(int));
  124.  
  125.     for (i = 0; i < NrGlossary; i++) {
  126.         if (Glossary[i].shortcut == NULL) continue;
  127.  
  128.         /* Write the options flag */
  129.         j = 0;
  130.         if (Glossary[i].dynamic) j |= 0x0001;
  131.         if (Glossary[i].hidden) j |= 0x0002;
  132.         write(fd, &j, sizeof(int));
  133.  
  134.         /* Write the short-cut */
  135.         len = kanjilen(Glossary[i].shortcut) + 1;
  136.         write(fd, &len, sizeof(int));
  137.         len *= sizeof(KANJI);
  138.         _lwrite(fd, (char far *) Glossary[i].shortcut, len);
  139.  
  140.         /* Write the phrase */
  141.         len = kanjilen(Glossary[i].phrase) + 1;
  142.         write(fd, &len, sizeof(int));
  143.         len *= sizeof(KANJI);
  144.         _lwrite(fd, (char far *) Glossary[i].phrase, len);
  145.     }
  146.  
  147.     close(fd);
  148. }
  149.  
  150.  
  151.  
  152. int SearchGlossary (KANJI far *key)
  153. {
  154.     int len;
  155.     int top, bottom, middle;
  156.     int diff;
  157.  
  158.  
  159.     if (NrGlossary <= 0) return (-2);
  160.  
  161.  
  162.     /* Now binary search */
  163.  
  164.     top = 0;
  165.     bottom = NrGlossary - 1;
  166.  
  167.     len = kanjilen(key);
  168.  
  169.     if (!kanjicmp(key, Glossary[top].shortcut)) {
  170.         if (Glossary[top].dynamic) return (top);
  171.     } else if (!kanjincmp(key, Glossary[top].shortcut, len)) {
  172.         if (Glossary[top].dynamic) return (-1);
  173.     }
  174.  
  175.     if (!kanjicmp(key, Glossary[bottom].shortcut)) {
  176.         return (Glossary[bottom].dynamic ? bottom : -2);
  177.     } else if (!kanjincmp(key, Glossary[bottom].shortcut, len)) {
  178.         return (Glossary[bottom].dynamic ? -1 : -2);
  179.     }
  180.  
  181.  
  182.     for (;;) {
  183.         middle = (top + bottom) / 2;
  184.  
  185.         diff = kanjicmp(key, Glossary[middle].shortcut);
  186.  
  187.         if (diff == 0) {
  188.             return (Glossary[middle].dynamic ? middle : -2);
  189.         }
  190.  
  191.         if (top >= bottom - 1) {
  192.             for (; bottom < NrGlossary; bottom++) {
  193.                 diff = kanjincmp(key, Glossary[bottom].shortcut, len);
  194.                 if (!Glossary[bottom].dynamic || diff != 0) continue;
  195.                 return (-1);
  196.             }
  197.             return (-2);
  198.         }
  199.  
  200.         if (diff > 0) top = middle;
  201.         else bottom = middle;
  202.     }
  203. }
  204.  
  205.  
  206.  
  207. KANJI far *GetGlossary (int index)
  208. {
  209.     return (Glossary[index].phrase);
  210. }
  211.  
  212.  
  213.  
  214.  
  215. BOOL FAR PASCAL EditGlossaryProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  216. {
  217.     switch (message) {
  218.         case WM_INITDIALOG: {
  219.             int i;
  220.             FILEOPTIONS *f;
  221.             KANJI buf[BUFSIZE];
  222.  
  223.             /* Set the type and mode-change icon */
  224.             SendDlgItemMessage(hwnd, 4201, EM_SETMODIFY, FN_CONTROL | FN_NOKANJI, 0L);
  225.             SendDlgItemMessage(hwnd, 4201, EM_SETRECT, GetDlgItem(hwnd, 4211), 0L);
  226.  
  227.             SendDlgItemMessage(hwnd, 4202, EM_SETMODIFY, FN_CONTROL, 0L);
  228.             SendDlgItemMessage(hwnd, 4202, EM_SETRECT, GetDlgItem(hwnd, 4211), 0L);
  229.  
  230.             f = (FILEOPTIONS *) SendDlgItemMessage(hwnd, 4201, EM_GETHANDLE, 0, 0L);
  231.             SendDlgItemMessage(hwnd, 4211, EM_SETHANDLE, f->hwnd, 0L);  /* mode-change icon */
  232.  
  233.             if (CurrentShortCut != NULL) {
  234.                 SendDlgItemMessage(hwnd, 4201, EM_REPLACESEL, 0, (LONG) CurrentShortCut);
  235.                 SetFocus(GetDlgItem(hwnd, 4202));
  236.             }
  237.  
  238.             if (CurrentPhrase != NULL) {
  239.                 /* Edit */
  240.                 SendDlgItemMessage(hwnd, 4202, EM_REPLACESEL, 0, (LONG) CurrentPhrase);
  241.                 i = kanjilen(CurrentPhrase);
  242.                 SendDlgItemMessage(hwnd, 4202, EM_SETSEL, i, MAKELONG(0, i-1));
  243.                 SetWindowText(GetDlgItem(hwnd, 1), "&Done!");
  244.                 SetWindowText(hwnd, "Edit an Existing Glossary Item");
  245.             } else {
  246.                 /* Add */
  247.                 SetWindowText(GetDlgItem(hwnd, 1), "&Add!");
  248.                 SetWindowText(hwnd, "Add a Glossary Item");
  249.             }
  250.  
  251.             CenterDialogBox(hwnd);
  252.             return (TRUE);
  253.         }
  254.  
  255.         case WM_COMMAND:
  256.             switch (wParam) {
  257.                 case IDCANCEL:
  258.                     CurrentShortCut = CurrentPhrase = NULL;
  259.                     EndDialog(hwnd, FALSE);
  260.                     return (TRUE);
  261.  
  262.                 case IDOK: {
  263.                     int i;
  264.                     UNIT far *up, far *up1;
  265.                     KANJI ch;
  266.  
  267.                     up1 = (UNIT far *) SendDlgItemMessage(hwnd, 4202, EM_GETLINE, 0, 0L);
  268.                     if (unitlen(up1) <= 0) {
  269.                         ErrorMessage(hwnd, "Sorry, you must enter a phrase for the short-cut.");
  270.                         SetFocus(GetDlgItem(hwnd, 4202));
  271.                         return (TRUE);
  272.                     }
  273.  
  274.                     up = (UNIT far *) SendDlgItemMessage(hwnd, 4201, EM_GETLINE, 0, 0L);
  275.                     if (unitlen(up) <= 0) {
  276.                         ErrorMessage(hwnd, "Sorry, you must enter a short-cut for the phrase.");
  277.                         SetFocus(GetDlgItem(hwnd, 4201));
  278.                         return (TRUE);
  279.                     }
  280.  
  281.                     CurrentShortCut = (KANJI far *) BlockAlloc((unitlen(up) + 5) * sizeof(KANJI));
  282.                     for (i = 0; up[i].kanji; i++) CurrentShortCut[i] = up[i].kanji;
  283.                     CurrentShortCut[i] = 0;
  284.  
  285.                     CurrentPhrase = (KANJI far *) BlockAlloc((unitlen(up1) + 5) * sizeof(KANJI));
  286.                     for (i = 0; up1[i].kanji; i++) CurrentPhrase[i] = up1[i].kanji;
  287.                     CurrentPhrase[i] = 0;
  288.  
  289.                     EndDialog(hwnd, TRUE);
  290.                     return (TRUE);
  291.                 }
  292.             }
  293.             return (TRUE);
  294.  
  295.         case WM_PAINT: {
  296.             HDC hdc;
  297.             PAINTSTRUCT ps;
  298.  
  299.             hdc = BeginPaint(hwnd, &ps);
  300.  
  301.             DrawBoundingBox(hwnd, hd